package netWork;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TcpEchoSever {

    //tcp服务器

  private ServerSocket serverSocket = null;

    public TcpEchoSever(int port) throws IOException {
        serverSocket = new ServerSocket(port);
    }
    public void start() throws IOException {
        System.out.println("服务器启动");
            ExecutorService pool = Executors.newFixedThreadPool(10);//构建一个10个线程的线程池

        while (true){
            //回阻塞,所以声明异常
            Socket clientSocket = serverSocket.accept() ;
            pool.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        processConnection(clientSocket);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });

        }
    }

    private void processConnection(Socket clientSocket) throws IOException {

        try (InputStream inputStream = clientSocket.getInputStream();
        OutputStream outputStream = clientSocket.getOutputStream();){
            Scanner scanner = new Scanner(inputStream);
            PrintWriter printWriter = new PrintWriter(outputStream);
            System.out.printf("客户端上线 [%s : %d]\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());

            while (true){
                if(!scanner.hasNext()){//如果对端没有数据就会返回false
                    //为空就退出
                    System.out.printf("客户端下线 [%s : %d ]\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());
                    break;
                }
                //处理多个请求
                //根据请求计算响应
                String request = scanner.next();//next读取操作是不带换行的
                //对字符串进行处理
                String response = process(request);
                printWriter.println(response);//带上换行,这样才可以让客户端区分从哪里到哪里是一个完整的响应
                printWriter.flush();
                System.out.printf("[%s:%d],req %s resp %s\n",clientSocket.getInetAddress().toString(),clientSocket.getPort(),request,response);

            }

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //由于上述可以推出循环,所以client可以对多个客户端进行操作,所以需要关闭
            clientSocket.close();
        }

    }

    private String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        TcpEchoSever tcpEchoSever = new TcpEchoSever(9090);
        tcpEchoSever.start();
    }
}
